package cn.com.wxd.amumu.search.core;

import java.io.IOException;
import java.nio.file.Paths;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hankcs.lucene.HanLPAnalyzer;

import cn.com.wxd.amumu.search.ReturnContentType;

/**
 * @author WangXuDong
 *         索引查询类
 * @version 1.0
 */
public class IndexSearch {
    private static final Logger log = LoggerFactory.getLogger(IndexSearch.class);

    /**
     * 查询
     *
     * @param keyWord            关键字
     * @param filePath           索引文件地址
     * @param returnContent  返回的属性 (目前为id 或者content)
     * @param recordCount        每次返回最大记录数和pagesize一样
     * @param pageIndex          页标从1开始
     *
     * @return 返回ID数组
     *
     * @throws Exception 文件读取错误
     */
    public String[] search(String keyWord, String filePath, ReturnContentType returnContent, int recordCount, int pageIndex)
            throws Exception {
        IndexReader reader = null;
        String[] searchResult;
        keyWord = keyWord.replaceAll("/", " ");
        keyWord = keyWord.replaceAll("\\\\", " "); //替换反斜杠为空格replace中\\\\代表反斜杠
        try (Directory dir = FSDirectory.open(Paths.get(filePath))) {
            reader = DirectoryReader.open(dir);
            IndexSearcher searcher = new IndexSearcher(reader);

            //Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_44);   //效果不好，
            //Analyzer analyzer = new IKAnalyzer(); //使用IK分词器效果显著
            Analyzer analyzer = new HanLPAnalyzer(); //使用自然语言分词器分词
            QueryParser queryParser = new QueryParser("content", analyzer);
            Query query = queryParser.parse(keyWord);

            //最小查询  不支持中文
            //Term term = new Term("content",keyWord);
            //TermQuery query = new TermQuery(term);

            //组合查询
            /*
             *
             BooleanQuery query=new BooleanQuery();
             //-----------地名带有字
             Term term1=new Term("content", keyWord);
             TermQuery tq1=new TermQuery(term1);
             BooleanClause clause=new BooleanClause(tq1, BooleanClause.Occur.SHOULD);
             query.add(clause);

             //--------权重最高的
             Term term2=new Term("author", keyWord);
             TermQuery tq2=new TermQuery(term2);
             BooleanClause clause2=new BooleanClause(tq2, BooleanClause.Occur.MUST);
             query.add(clause2);
             */
            if (recordCount < 0) {
                recordCount = 0;
            }
            if (pageIndex < 0) {
                pageIndex = 1;
            }

            TopDocs topdocs = searcher.search(query, recordCount * pageIndex);   //后面的参数是读取几条结果
            ScoreDoc[] scoreDocs = topdocs.scoreDocs;
            //给查询结果赋值
            searchResult = new String[scoreDocs.length];
            for (int i = (pageIndex - 1) * recordCount; i < scoreDocs.length; i++) {
                float score = scoreDocs[i].score;
                if (score > 0.1) {//评分大于0.1的做保留，其他全不要
                    int doc = scoreDocs[i].doc;    //获取查询到的值
                    Document document = searcher.doc(doc);
                    log.info("id--" + scoreDocs[i].doc + "---scors--" + scoreDocs[i].score + "---index--"
                            + scoreDocs[i].shardIndex);
                    String val = document.get(returnContent.getValue());
                    if (val != null && (!val.trim().equals(""))) {
                        searchResult[i] = val;//赋给结果
                    }
                }
            }
        } catch (Exception e) {
            log.error("读取索引文件错误" + e.getMessage(), e);
            throw e;
        }
        finally {
            if (reader != null) {
                reader.close();
            }
        }
        return searchResult;
    }
}
